﻿using Huasky.Gm.Application.FaultHandle.Dtos;
using Microsoft.CodeAnalysis.Operations;

namespace Huasky.Gm.Application;

public class FaultHandleService : IFaultHandleService, ITransient
{
    private readonly IRepository<FaultRecord> repository;
    public List<FaultRecordDto> Records { get; set; } = new List<FaultRecordDto>();

    public FaultHandleService(IRepository<FaultRecord> repository)
    {
        this.repository = repository;
    }
    public async Task<List<FaultRecordDto>> GetFaultRecordsAsync(FaultRecordParams para)
    {
        if (string.IsNullOrWhiteSpace(para.Key)) throw new ArgumentNullException("请输入搜索关键字！");
        await LoadRecordsAsync();
        var dtos = Records.Where(a => a.Code.Contains(para.Key) || a.Phenomenon.Contains(para.Key)).Take(20).ToList();
        return dtos;
    }

    public async Task<FaultRecordDto> AddFaultRecordAsync(AddFaultRecordDto dto)
    {
        await LoadRecordsAsync();
        if (dto.Id != default && Records.Any(a => a.Id == dto.Id))
        {
            return await UpdateFaultRecordAsync(dto);
        }
        var old = Records.FirstOrDefault(a => a.Code == dto.Code);
        if (old != null) throw new Exception($"已存在故障编号为【{dto.Code}】的记录");
        var entity = dto.Adapt<FaultRecord>();
        entity.GenId();
        entity.CreatedTime = DateTimeOffset.Now;

        dto.Info.Images = dto.Adds.Select(SaveImage).ToList();
        entity.ExtJson = dto.Info.ToJson();
        await repository.InsertAsync(entity);
        await repository.SaveNowAsync();
        var record = entity.Adapt<FaultRecordDto>();
        Records.Add(record);
        return record;
    }

    public async Task RemoveFaultRecordAsync(Guid id)
    {
        await LoadRecordsAsync();
        await repository.UpdateIncludeAsync(new FaultRecord { Id = id, IsDelete = true, UpdatedTime = DateTimeOffset.Now }, new[] { nameof(FaultRecord.IsDelete), nameof(FaultRecord.UpdatedTime) });
        await repository.SaveNowAsync();
        var record = Records.FirstOrDefault(a => a.Id == id);
        if (record == null) return;
        Records.Remove(record);
    }

    public async Task<FaultRecordDto> UpdateFaultRecordAsync(AddFaultRecordDto dto)
    {
        await LoadRecordsAsync();
        var entity = await repository.FindOrDefaultAsync(dto.Id);
        if (entity == null) return null;
        entity.Type = dto.Type;
        entity.Code = dto.Code;
        entity.Phenomenon = dto.Phenomenon;
        entity.Responsibility = dto.Responsibility;
        entity.Result = dto.Result;
        dto.Removes.ForEach(a =>
        {
            dto.Info.Images.Remove(a);
            RemoveImage(a);
        });
        dto.Info.Images.AddRange(dto.Adds.Select(SaveImage));
        entity.ExtJson = dto.Info.ToJson();
        entity.UpdatedTime = DateTimeOffset.Now;
        await repository.SaveNowAsync();
        var record = entity.Adapt<FaultRecordDto>();
        var old = Records.FirstOrDefault(a => a.Id == dto.Id);
        if (old != null) Records.Remove(old);
        Records.Add(record);
        return record;
    }

    private async Task LoadRecordsAsync()
    {
        if (Records.Count > 0) return;
        var entities = await repository.Where(a => !a.IsDelete)
                    .AsNoTracking()
                    .ToListAsync();
        Records = entities.Select(a => a.Adapt<FaultRecordDto>()).ToList();
    }


    private string SaveImage(AddFaultRecordImage image)
    {
        var buffer = Convert.FromBase64String(image.Source);
        var filename = $"{Guid.NewGuid()}.{image.Type}".ToLower();
        File.WriteAllBytes(Path.Combine(GetImageDir(), filename), buffer);
        return filename;
    }

    private void RemoveImage(string filename)
    {
        var path = GetImageDir() + "\\" + filename;
        File.Delete(path);
    }

    private string GetImageDir() => Path.Combine(App.HostEnvironment.ContentRootPath, "wwwroot", "images");

}
